import { Subject, Observable } from 'rxjs'
import { DesignerCommand, StandardCommandInvoker } from './CommandSystem'
import { PropertyEditorRegistry } from './PropertyEditorRegistry'
import { DesignerState } from './DesignerState'
import { WidgetDescriptor } from './WidgetProtocol'

export const DESIGNER_EXTENSION_POINT = {
  WIDGET_REGISTRY: Symbol('widget.registry'),
  STATE_MANAGER: Symbol('state.manager'),
  COMMAND_EXECUTOR: Symbol('command.executor'),
  PROPERTY_EDITOR: Symbol('property.editor')
}

export class DesignerEngine {
  private readonly widgetRegistry = new Map<string, WidgetDescriptor>()
  private readonly extensionPoints = new Map<symbol, any>()
  private readonly propertyEditorRegistry = new PropertyEditorRegistry()
  private readonly designerState = new DesignerState()
  
  private readonly selectionChanged$ = new Subject<string>()
  private readonly widgetTreeChanged$ = new Subject<void>()

  constructor() {
    // 注册组件注册表
    this.registerExtension(DESIGNER_EXTENSION_POINT.WIDGET_REGISTRY, {
      registerWidget: (descriptor: WidgetDescriptor) => {
        this.widgetRegistry.set(descriptor.type, descriptor)
        this.widgetTreeChanged$.next()
      },
      getWidget: (type: string) => this.widgetRegistry.get(type)
    })
    
    // 注册命令执行器
    this.registerExtension(
      DESIGNER_EXTENSION_POINT.COMMAND_EXECUTOR, 
      new StandardCommandInvoker()
    )
    
    // 注册状态管理器
    this.registerExtension(DESIGNER_EXTENSION_POINT.STATE_MANAGER, {
      setState: (key: string, value: any) => this.designerState.setState(key, value),
      getState: (key: string) => this.designerState.getState(key),
      batchUpdate: (updates: Record<string, any>) => this.designerState.batchUpdate(updates),
      getFullState: () => this.designerState.getFullState(),
      resetState: (initialState?: Record<string, any>) => this.designerState.resetState(initialState)
    })
    
    // 注册属性编辑器注册表
    this.registerExtension(DESIGNER_EXTENSION_POINT.PROPERTY_EDITOR, {
      registerEditor: (type: string, component: any) => 
        this.propertyEditorRegistry.registerEditor(type, component),
      getEditor: (type: string) => 
        this.propertyEditorRegistry.getEditor(type),
      getRegisteredTypes: () => 
        this.propertyEditorRegistry.getRegisteredTypes()
    })
  }

  registerExtension(point: symbol, impl: any) {
    this.extensionPoints.set(point, impl)
  }

  getExtension<T>(point: symbol): T {
    return this.extensionPoints.get(point)
  }

  // 核心事件流
  get onSelectionChanged() {
    return this.selectionChanged$.asObservable()
  }

  get onWidgetTreeChanged() {
    return this.widgetTreeChanged$.asObservable()
  }
}

export interface CommandExecutor {
  execute(command: DesignerCommand): void
  undo(): void
  redo(): void
  onCommand: Observable<DesignerCommand | undefined>
}

export interface PropertyEditor {
  registerEditor(type: string, component: any): void
  getEditor(type: string): any | undefined
  getRegisteredTypes(): string[]
}